package claim.geoobj;

import claim.fuzzy.LinearMembershipFunction;
import claim.fuzzy.MembershipFunction;
import claim.geom.Feature;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;

/** A transition zone in the boundary area of a geographical object.
 * @author <a href="mailto:christoph.kinkeldey@hcu-hamburg.de">Christoph Kinkeldey</a>
 *
 */
public class TransitionZone {
	
	private String id;
	private String objId;
	private Buffer buffer;
	private MembershipFunction function;

	public TransitionZone(String objId, Buffer buffer) {
		this(objId, buffer, new LinearMembershipFunction());
	}
	
	public TransitionZone(String objId, Buffer buffer, MembershipFunction function) {
		this.id = buffer.getId();
		this.setObjId(objId);
		this.buffer = buffer;
		this.function = function;
	}
	
	public String getId() {
		return id;
	}
	
	public double getMembership(double x, double y) {
		if (!pointWithin(x, y)) {
			return 0;
		} else {
			float t = determineT(x, y);
			if (t >= 0.0 && t <= 1.0) {
				return function.getValue(t);
			} else {
				return -1; 
			}
		}
	}
	
	private float determineT(double x, double y) {
		Point point = new GeometryFactory().createPoint(new Coordinate(x, y));
		double distOuter = point.distance(buffer.getNeighBoundary());
		double distInner = point.distance(buffer.getObjBoundary());
		return Math.round(distInner / (distInner+distOuter) * 1000.)/1000.f;
	}

	public Boolean pointWithin(double x, double y) {
		Point point = new GeometryFactory().createPoint(new Coordinate(x, y));
		return buffer.getGeometry().intersects(point);
	}

	public void setObjId(String objId) {
		this.objId = objId;
	}

	public String getObjId() {
		return objId;
	}

}
